import { prototype as ArrayPrototype } from "./ArrayPrototype.js";
import { watchers as computedWatchers } from "./ComputedWatcher.js";
import Dep from "./Dep.js";
export default class Observe {
  constructor(vm, data) {
    this.vm = vm;
    this.walk(data);
  }
  walk(data) {
    if (typeof data !== "object" || data == null) return;
    if (Array.isArray(data)) {
      //重置原型对象
      Object.setPrototypeOf(data, ArrayPrototype);
      data;
    }
    Object.keys(data).forEach((key) => {
      this.defineReactive(data, key, data[key]);
    });
  }

  defineReactive(data, key, value) {
    this.walk(value);
    const dep = new Dep();
    Object.defineProperty(data, key, {
      get() {
        window.$watcher && dep.push(window.$watcher);
        return value;
      },
      set: (newValue) => {
        if (newValue == value) return;
        //调用一个动作，更新界面
        this.walk(newValue);
        value = newValue;
        dep.notify(this.vm);

        computedWatchers.map((w) => w.update());
      },
    });
  }
}
